package com.xpec.c4.db.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;

import com.ms.player.PlayerSwitchList;
import com.xpec.c4.db.model.basic.BasicGameModel;
import com.xpec.c4.game.common.Helper;
import com.xpec.c4.game.datamanager.agent.money.CoinType;


/**
 * 活跃玩家数据
 * 
 * @author lipeilin
 * @2011-5-14 下午05:13:44
 * 
 */
@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)
@Table(name = "players", uniqueConstraints = {
		@UniqueConstraint(columnNames = { "guid" }),
		@UniqueConstraint(columnNames = { "name" , "nameNumber"}),
		@UniqueConstraint(columnNames = { "inviteCode" })
		})
@org.hibernate.annotations.Table(
		appliesTo = "players", indexes = {
				@org.hibernate.annotations.Index(name = "IDX_ACCOUNT_ID", columnNames = { "accountId" }),
				@org.hibernate.annotations.Index(name = "NAME_INDEX", columnNames = { "name" }),
				@org.hibernate.annotations.Index(name = "UPLINE_CODE_INDEX", columnNames = { "uplineCode" }),
				@org.hibernate.annotations.Index(name = "UPLINE_ID_INDEX", columnNames = { "uplineId" }),
				@org.hibernate.annotations.Index(name = "IDX_COOP_ACCOUNT_ID", columnNames = { "cooperatorAccountId"})
		})
public class PlayerModel extends BasicGameModel implements Serializable {
	// 當此物件出現在其他table物件中時一定要實作Serializable (JPA 2.1)
	private static final long serialVersionUID = -3811227381334782100L;

	public PlayerModel() {

	}

	public PlayerModel(String name, String guid, String facephoto) {
		this.name = name;
		this.guid = guid;
		this.facephoto = facephoto;
	}

	public PlayerModel(String guid, int errorTimes, long disableTime, int errorTimesGift, long disableTimeGift){
		this.guid = guid;
		this.errorTimes = errorTimes;
		this.disableTime = disableTime;
		this.errorTimesGift = errorTimesGift;
		this.disableTimeGift = disableTimeGift;
	}

	/**
	 * 自身id
	 */
	private String guid;

	/**
	 * 帳戶id
	 */
	private String accountId;
	
	/**
	 * 營運商accountID
	 */
	private String cooperatorAccountId;

	/**
	 * 頭像
	 */
	private String facephoto;

	/**
	 * 性別 1 男 0 女
	 */
	private boolean gender;

	/**
	 * 等级
	 */
	protected int level;

	/**
	 * 經驗 (這一生的總押注金額)
	 */
	private BigDecimal exp;

	/**
	 * 名稱
	 */
	private String name;

	/**
	 * 金幣
	 */
	private BigDecimal goldCoin;

	/**
	 * 暫存錢包的錢
	 */
	private BigDecimal tmpCash;

	/**
	 * 銀行金幣
	 */
	private BigDecimal bankGoldCoin;

	/**
	 * vip等級
	 */
	private int vip;

	/**
	 * vip累積值 (轉點到角色身上的總額)
	 */
	private long vipExp;

	/**
	 * 試玩幣
	 */
	private BigDecimal trialCoin;

	/**
	 * 幸運金
	 */
	private BigDecimal luckyCoin;

	/**
	 * 所在的 zone id
	 */
	private String zoneId;

	/**
	 * 包月到期時間
	 */
	private Date monthlyFeeEndTime;

	/**
	 * 包月領取階段 0 ~ 29 個領取階段
	 */
	private int monthlyFeePayStage;

	/**
	 * 包週到期時間
	 */
	private Date weeklyFeeEndTime;

	/**
	 * 包週領取階段 0 ~ 29 個領取階段
	 */
	private int weeklyFeePayStage;

	/**
	 * 玩家最近一次的的登錄時間(切換zone)
	 */
	private Date loginTime;

	/**
	 * 玩家最近一次的離線時間
	 */
	private Date logoutTime;

	/**
	 * 角色創建時間
	 */
	private Date createTime;

	/**
	 * 玩家最近一次的的登錄時間
	 */
	private Date lastloginTime;
	
	/**
	 * 玩家最近一次的的登錄IP位置
	 */
	private String lastloginIP;
	
	/**
	 * 創建角色平台
	 */
	private String 	registeredPlatform;
	
	/**
	 * 最後一次登入的平台
	 */
	private String lastLoginPlatform;
	
	/**
	 * 領取包月獎勵 (最後一次領取包月獎勵的時間)
	 */
	private Date monthlyAwardTime;

	/**
	 * 領取包週獎勵 (最後一次領取包週獎勵的時間)
	 */
	private Date weeklyAwardTime;

	/**
	 * 角色名稱被修改的時間
	 */
	private Date nameModifyTime;

	/**
	 * 是否為試玩帳號
	 */
	private boolean trialAccount = false;

	/**
	 * 禁言效果過期時間
	 */
	private long silentExpireTime;

	/**
	 * 自己的邀請碼
	 */
	private String inviteCode;

	/**
	 * 上線的邀請碼
	 */
	private String uplineCode;

	/**
	 * 上線的ID
	 */
	private String uplineId;
	
	/**
	 * 是否把上線的邀請獎勵 加到回饋金
	 */
	private boolean addUplineInviteReward;

	/**
	 * 銀行密碼輸入錯誤次數
	 */
	private int errorTimes;

	/**
	 * 5次錯誤後禁止時間
	 */
	private long disableTime;

	/**
	 * 禮物錯誤次數
	 */
	private int errorTimesGift;

	/**
	 * 禮物5次錯誤後禁止時間
	 */
	private long disableTimeGift;

	/**
	 * 玩家被禁止送禮天數
	 * */
	private int disableSendGiftDays;
	
	/**
	 * 玩家被強制禁止送禮 禁止時間
	 */
	private long disableSendGiftTime;

	/**
	 * 玩家被禁止送禮原因
	 */
	private String disableSendGiftReason;
	
	
	/**
	 * 最後一次取得自動回覆幸運金的時間 (ms)
	 */
	private long lastGetLuckyCoinTime;

	/**
	 * 跨日登入次數<br>
	 * 距離上次登入有跨日就+1，一次跨三天也是+1
	 */
	private int continuousLoginCount = 0;

	/*
	 * 首儲獎勵連續登入天數 
	 * 0等於沒有轉點過，ㄧ但轉點就從1開始算	 */
	private int storeRewardContinuousLoginCount;

	/**
	 * 是否為首創角色
	 */
	private boolean firstCreate;

	/**
	 * 首儲獎勵領取數量
	 */
	private int firstStoreReward;

	/**
	 * 離限掛機結果
	 */
	private String offlinePlayResult;

	/**
	 * 使用者類型 判斷是不是機器人 0是人，1是機器人(小樂)
	 */
	private int userType;
	
	/**
	 * 玩家身分
	 * 目前 :
	 * 0是一般玩家 
	 * 1是經銷商玩家 
	 * 2是經銷商下線 
	 * 3是經銷商下線的下線
	 */
	private byte playerIdentityType;
	
	/**
	 * 角色名稱後的隨機碼
	 */
	private String nameNumber;

	/**
	 * 水晶
	 */
	private int crystal;
	
	/**
	 * 被後台強制禁言時間
	 */
	private long banTalkTime;
	
	/**
	 * 被後台強制禁言的原因
	 */
	private String banTalkTimeReason;
	
	/**
	 * 是否可以產生抽傭金
	 */
	private boolean canMakeCommission = false;
	
	/**
	 * 玩家控制欄位(以Json的格式儲存)
	 * {@link PlayerSwitchList}
	 */
	private String playerSwitchList;

	/** 上一次 使用等級寶箱的等級*/
	private int lastLevelBoxUseLevel;
	
	/**
	 * 營運商 id
	 */
	private String venderId;
	
	/**
	 * 子營運商 id
	 */
	private String subVenderId;

	/**
	 * h5 agent 回傳資料時用的參數
	 */
	private String agentData;

	public boolean isFirstCreate() {
		return firstCreate;
	}

	public void setFirstCreate(boolean firstCreate) {
		this.firstCreate = firstCreate;
	}

	public int getFirstStoreReward() {
		return firstStoreReward;
	}

	public void setFirstStoreReward(int firstStoreReward) {
		this.firstStoreReward = firstStoreReward;
	}

	public int getStoreRewardContinuousLoginCount() {
		return storeRewardContinuousLoginCount;
	}

	public void setStoreRewardContinuousLoginCount(int storeRewardContinuousLoginCount) {
		this.storeRewardContinuousLoginCount = storeRewardContinuousLoginCount;
	}

	/**
	 * 取得角色身上指定幣別的錢
	 * 
	 * @param coinType
	 *            幣別
	 * @param value
	 *            數值
	 */
	public void setCoin(CoinType coinType, BigDecimal value) {
		switch (coinType) {
		case TRIAL:
			setTrialCoin(value);
			break;
		case GOLD:
			setGoldCoin(value);
			break;
		case LUCKY:
			setLuckyCoin(value);
			break;
		default:
			break;
		}
	}

	/**
	 * 取得角色身上指定幣別的錢
	 * 
	 * @param coinType
	 *            幣別
	 * @return 指定幣跌的錢
	 */
	public BigDecimal getCoin(CoinType coinType) {
		switch (coinType) {
		case TRIAL:
			return trialCoin;
		case GOLD:
			return goldCoin;
		case LUCKY:
			return luckyCoin;
		default:
			break;
		}

		return new BigDecimal(CoinType.UNKNOW_TYPE.getId());
	}

	public String getGuid() {
		return guid;
	}

	@Column(columnDefinition = "VARCHAR(255) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL")
	public String getAccountId() {
		return accountId;
	}

	@Column(columnDefinition = "VARCHAR(255) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL")
	public String getName() {
		return name;
	}
	
	@Column(precision = 19, scale = 2, columnDefinition = "DECIMAL(19,2) default 0.0")
	public BigDecimal getGoldCoin() {
		return goldCoin;
	}

	public void setGuid(String guid) {
		this.guid = guid;
	}

	public void setAccountId(String accountId) {
		this.accountId = accountId;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setGoldCoin(long goldCoin) {
		BigDecimal decimalGoldCoin = Helper.sub(this.goldCoin, new BigDecimal(this.goldCoin.longValue()));
		this.goldCoin = Helper.add( new BigDecimal(goldCoin), decimalGoldCoin);
	}
	
	public void setGoldCoin(BigDecimal goldCoin) {
		this.goldCoin = goldCoin;
	}

	public String getZoneId() {
		return zoneId;
	}

	public void setZoneId(String zoneId) {
		this.zoneId = zoneId;
	}

	@Column(columnDefinition = "VARCHAR(500) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL")
	public String getFacephoto() {
		return facephoto;
	}
	
	public void setFacephoto(String facephoto) {
		this.facephoto = facephoto;
	}

	public boolean isGender() {
		return gender;
	}

	public int getLevel() {
		return level;
	}

	public void setGender(boolean gender) {
		this.gender = gender;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getLoginTime() {
		return loginTime;
	}

	public void setLoginTime(Date loginTime) {
		this.loginTime = loginTime;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getLogoutTime() {
		return logoutTime;
	}

	public void setLogoutTime(Date logoutTime) {
		this.logoutTime = logoutTime;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getLastloginTime() {
		return lastloginTime;
	}

	public void setLastloginTime(Date lastloginTime) {
		this.lastloginTime = lastloginTime;
	}

	public String getLastloginIP() {
		return lastloginIP;
	}

	public void setLastloginIP(String lastloginIP) {
		this.lastloginIP = lastloginIP;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getMonthlyFeeEndTime() {
		return monthlyFeeEndTime;
	}

	public void setMonthlyFeeEndTime(Date monthlyFeeEndTime) {
		this.monthlyFeeEndTime = monthlyFeeEndTime;
	}

	public int getMonthlyFeePayStage() {
		return monthlyFeePayStage;
	}

	public void setMonthlyFeePayStage(int monthlyFeePayStage) {
		this.monthlyFeePayStage = monthlyFeePayStage;
	}

	public boolean isTrialAccount() {
		return trialAccount;
	}

	public void setTrialAccount(boolean trialAccount) {
		this.trialAccount = trialAccount;
	}

	@Column(precision = 19, scale = 2, columnDefinition = "DECIMAL(19,2) default 0.0")
	public BigDecimal getTrialCoin() {
		return trialCoin;
	}

	public void setTrialCoin(BigDecimal trialCoin) {
		this.trialCoin = trialCoin;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getNameModifyTime() {
		return nameModifyTime;
	}

	public void setNameModifyTime(Date nameModifyTime) {
		this.nameModifyTime = nameModifyTime;
	}

	@Column(precision = 19, scale = 2, columnDefinition = "DECIMAL(19,2) default 0.0")
	public BigDecimal getLuckyCoin() {
		return luckyCoin;
	}

	public void setLuckyCoin(BigDecimal luckyCoin) {
		this.luckyCoin = luckyCoin;
	}

	public int getVip() {
		return vip;
	}

	public void setVip(int vip) {
		this.vip = vip;
	}

	@Column(precision = 19, scale = 2, columnDefinition = "DECIMAL(19,2) default 0.0")
	public BigDecimal getBankGoldCoin() {
		return bankGoldCoin;
	}

	public void setBankGoldCoin(BigDecimal bankGoldCoin) {
		this.bankGoldCoin = bankGoldCoin;
	}

	public long getSilentExpireTime() {
		return silentExpireTime;
	}

	public void setSilentExpireTime(long silentExpireTime) {
		this.silentExpireTime = silentExpireTime;
	}

	public Date getMonthlyAwardTime() {
		return monthlyAwardTime;
	}

	public void setMonthlyAwardTime(Date monthlyAwardTime) {
		this.monthlyAwardTime = monthlyAwardTime;
	}

	public String getInviteCode() {
		return inviteCode;

	}

	public void setInviteCode(String inviteCode) {
		this.inviteCode = inviteCode;
	}

	public String getUplineCode() {
		return uplineCode;
	}

	public void setUplineCode(String uplineCode) {
		this.uplineCode = uplineCode;
	}

	public long getVipExp() {
		return vipExp;
	}

	public void setVipExp(long vipExp) {
		this.vipExp = vipExp;
	}

	public BigDecimal getExp() {
		return exp;
	}

	public void setExp(BigDecimal exp) {
		this.exp = exp;
	}

	public int getErrorTimes() {
		return errorTimes;
	}

	public long getDisableTime() {
		return disableTime;
	}

	public void setErrorTimes(int errorTimes) {
		this.errorTimes = errorTimes;
	}

	public void setDisableTime(long disableTime) {
		this.disableTime = disableTime;
	}

	public int getErrorTimesGift() {
		return errorTimesGift;
	}

	public long getDisableTimeGift() {
		return disableTimeGift;
	}

	public void setErrorTimesGift(int errorTimesGift) {
		this.errorTimesGift = errorTimesGift;
	}

	public void setDisableTimeGift(long disableTimeGift) {
		this.disableTimeGift = disableTimeGift;
	}

	public long getLastGetLuckyCoinTime() {
		return lastGetLuckyCoinTime;
	}

	public void setLastGetLuckyCoinTime(long lastGetLuckyCoinTime) {
		this.lastGetLuckyCoinTime = lastGetLuckyCoinTime;
	}

	public int getContinuousLoginCount() {
		return continuousLoginCount;
	}

	public void setContinuousLoginCount(int continuousLoginCount) {
		this.continuousLoginCount = continuousLoginCount;
	}

	public String getOfflinePlayResult() {
		return offlinePlayResult;
	}

	public void setOfflinePlayResult(String offlinePlayResult) {
		this.offlinePlayResult = offlinePlayResult;
	}

	public int getUserType() {
		return userType;
	}

	public void setUserType(int userType) {
		this.userType = userType;
	}
	@Column(columnDefinition="VARCHAR(255) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT ''")
	public String getNameNumber() {
		return nameNumber;
	}

	public void setNameNumber(String nameNumber) {
		this.nameNumber = nameNumber;
	}	
	
	public long getDisableSendGiftTime() {
		return disableSendGiftTime;
	}

	public void setDisableSendGiftTime(long disableSendGiftTime) {
		this.disableSendGiftTime = disableSendGiftTime;
	}

	public String getDisableSendGiftReason() {
		return disableSendGiftReason;
	}

	public void setDisableSendGiftReason(String disableSendGiftReason) {
		this.disableSendGiftReason = disableSendGiftReason;
	}
	
	public int getDisableSendGiftDays() {
		return disableSendGiftDays;
	}

	public void setDisableSendGiftDays(int disableSendGiftDays) {
		this.disableSendGiftDays = disableSendGiftDays;
	}
	public int getCrystal() {
		return crystal;
	}

	public void setCrystal(int crystal) {
		this.crystal = crystal;
	}	public String getUplineId() {
		return uplineId;
	}

	public void setUplineId(String uplineId) {
		this.uplineId = uplineId;
	}
	
	public boolean isAddUplineInviteReward() {
		return addUplineInviteReward;
	}

	public void setAddUplineInviteReward(boolean addUplineInviteReward) {
		this.addUplineInviteReward = addUplineInviteReward;
	}
	
	public long getBanTalkTime() {
		return banTalkTime;
	}

	public void setBanTalkTime(long banTalkTime) {
		this.banTalkTime = banTalkTime;
	}
	
	@Column(columnDefinition="VARCHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT ''")
	public String getBanTalkTimeReason() {
		return banTalkTimeReason;
	}

	public void setBanTalkTimeReason(String banTalkTimeReason) {
		this.banTalkTimeReason = banTalkTimeReason;
	}
	
	public boolean isCanMakeCommission() {
		return canMakeCommission;
	}

	public void setCanMakeCommission(boolean canMakeCommission) {
		this.canMakeCommission = canMakeCommission;
	}

	public byte getPlayerIdentityType() {
		return playerIdentityType;
	}

	public void setPlayerIdentityType(byte playerIdentityType) {
		this.playerIdentityType = playerIdentityType;
	}

	public String getLastLoginPlatform() {
		return lastLoginPlatform;
	}

	public void setLastLoginPlatform(String lastLoginPlatform) {
		this.lastLoginPlatform = lastLoginPlatform;
	}

	public String getRegisteredPlatform() {
		return registeredPlatform;
	}

	public void setRegisteredPlatform(String registeredPlatform) {
		this.registeredPlatform = registeredPlatform;
	}

	public String getPlayerSwitchList() {
		return playerSwitchList;
	}

	public void setPlayerSwitchList(String playerSwitchList) {
		this.playerSwitchList = playerSwitchList;
	}

	public int getLastLevelBoxUseLevel() {
		return lastLevelBoxUseLevel;
	}

	public void setLastLevelBoxUseLevel(int lastLevelBoxUseLevel) {
		this.lastLevelBoxUseLevel = lastLevelBoxUseLevel;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getWeeklyFeeEndTime() {
		return weeklyFeeEndTime;
	}

	public void setWeeklyFeeEndTime(Date weeklyFeeEndTime) {
		this.weeklyFeeEndTime = weeklyFeeEndTime;
	}

	public int getWeeklyFeePayStage() {
		return weeklyFeePayStage;
	}

	public void setWeeklyFeePayStage(int weeklyFeePayStage) {
		this.weeklyFeePayStage = weeklyFeePayStage;
	}

	@Temporal(TemporalType.TIMESTAMP)
	public Date getWeeklyAwardTime() {
		return weeklyAwardTime;
	}

	public void setWeeklyAwardTime(Date weeklyAwardTime) {
		this.weeklyAwardTime = weeklyAwardTime;
	}

	public String getCooperatorAccountId() {
		return cooperatorAccountId;
	}

	public void setCooperatorAccountId(String cooperatorAccountId) {
		this.cooperatorAccountId = cooperatorAccountId;
	}

	@Column(columnDefinition="VARCHAR(50) NOT NULL default 'TONWA'")
	public String getVenderId() {
		return venderId;
	}

	public void setVenderId(String venderId) {
		this.venderId = venderId;
	}

	@Column(columnDefinition="VARCHAR(50) NOT NULL default 'TONWA'")
	public String getSubVenderId() {
		return subVenderId;
	}

	public void setSubVenderId(String subVenderId) {
		this.subVenderId = subVenderId;
	}

	public String getAgentData() {
		return agentData;
	}

	public void setAgentData(String agentData) {
		this.agentData = agentData;
	}

	@Column(precision = 19, scale = 2, columnDefinition = "DECIMAL(19,2) default 0.0")
	public BigDecimal getTmpCash() {
		return tmpCash;
	}

	public void setTmpCash(BigDecimal tmpCash) {
		this.tmpCash = tmpCash;
	}
}
